41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h
3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec
3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h
-40589968oCfoUlXd460CjVAkBE8IBA tools/libxc/xc_atropos.c
3fbba6dbEVkVMX0JuDFzap9jeaucGA tools/libxc/xc_bvtsched.c
3fbba6dbasJQV-MVElDC0DGSHMiL5w tools/libxc/xc_domain.c
40278d99BLsfUv3qxv0I8C1sClZ0ow tools/libxc/xc_elf.h
3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c
3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h
42337174PxyzzPk62raDiYCIsfStDg tools/libxc/xc_ptrace.c
-40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c
41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c
40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile
40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c
3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c
4051bcecFeq4DE70p4zGO5setf47CA xen/common/physdev.c
3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/common/resource.c
-4064773cJ31vZt-zhbSoxqft1Jaw0w xen/common/sched_atropos.c
40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c
-40589968be_t_n0-w6ggceW7h-sx0w xen/common/sched_rrobin.c
3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c
3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c
INCLUDES += -I $(XEN_LIBXUTIL)
SRCS :=
-SRCS += xc_atropos.c
SRCS += xc_bvtsched.c
SRCS += xc_domain.c
SRCS += xc_evtchn.c
SRCS += xc_physdev.c
SRCS += xc_private.c
SRCS += xc_ptrace.c
-SRCS += xc_rrobin.c
SRCS += xc_vmx_build.c
CFLAGS += -Wall
long long *warpl,
long long *warpu);
-int xc_atropos_domain_set(int xc_handle,
- u32 domid,
- u64 period, u64 slice, u64 latency,
- int xtratime);
-
-int xc_atropos_domain_get(int xc_handle,
- u32 domid,
- u64* period, u64 *slice, u64 *latency,
- int *xtratime);
-
-int xc_rrobin_global_set(int xc_handle, u64 slice);
-
-int xc_rrobin_global_get(int xc_handle, u64 *slice);
-
typedef evtchn_status_t xc_evtchn_status_t;
/*
+++ /dev/null
-/******************************************************************************
- * xc_atropos.c
- *
- * API for manipulating parameters of the Atropos scheduler.
- *
- * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge.
- */
-
-#include "xc_private.h"
-
-int xc_atropos_domain_set(int xc_handle,
- u32 domid, u64 period, u64 slice, u64 latency,
- int xtratime)
-{
- dom0_op_t op;
- struct atropos_adjdom *p = &op.u.adjustdom.u.atropos;
-
- op.cmd = DOM0_ADJUSTDOM;
- op.u.adjustdom.domain = (domid_t)domid;
- op.u.adjustdom.sched_id = SCHED_ATROPOS;
- op.u.adjustdom.direction = SCHED_INFO_PUT;
-
- p->nat_period = period;
- p->nat_slice = slice;
- p->latency = latency;
- p->xtratime = xtratime;
-
- return do_dom0_op(xc_handle, &op);
-}
-
-int xc_atropos_domain_get(int xc_handle, u32 domid, u64 *period,
- u64 *slice, u64 *latency, int *xtratime)
-{
- dom0_op_t op;
- int ret;
- struct atropos_adjdom *p = &op.u.adjustdom.u.atropos;
-
- op.cmd = DOM0_ADJUSTDOM;
- op.u.adjustdom.domain = (domid_t)domid;
- op.u.adjustdom.sched_id = SCHED_ATROPOS;
- op.u.adjustdom.direction = SCHED_INFO_GET;
-
- ret = do_dom0_op(xc_handle, &op);
-
- *period = p->nat_period;
- *slice = p->nat_slice;
- *latency = p->latency;
- *xtratime = p->xtratime;
-
- return ret;
-}
int ret;
/* Figure out which scheduler is currently used: */
- if((ret = xc_sched_id(xc_handle, &sched_id)))
+ if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
return ret;
- switch(sched_id)
+ switch ( sched_id )
{
case SCHED_BVT:
{
/* Preserve all the scheduling parameters apart
of MCU advance. */
- if((ret = xc_bvtsched_domain_get(xc_handle, domid, &mcuadv,
- &warpback, &warpvalue, &warpl, &warpu)))
+ if ( (ret = xc_bvtsched_domain_get(
+ xc_handle, domid, &mcuadv,
+ &warpback, &warpvalue, &warpl, &warpu)) != 0 )
return ret;
/* The MCU advance is inverse of the weight.
Default value of the weight is 1, default mcuadv 10.
The scaling factor is therefore 10. */
- if(weight > 0) mcuadv = 10 / weight;
+ if ( weight > 0 )
+ mcuadv = 10 / weight;
ret = xc_bvtsched_domain_set(xc_handle, domid, mcuadv,
warpback, warpvalue, warpl, warpu);
break;
}
-
- case SCHED_RROBIN:
- {
- /* The weight cannot be set for RRobin */
- break;
- }
- case SCHED_ATROPOS:
- {
- /* TODO - can we set weights in Atropos? */
- break;
- }
}
return ret;
+++ /dev/null
-/******************************************************************************
- * xc_rrobin.c
- *
- * API for manipulating parameters of the Round Robin scheduler
- *
- * by Mark Williamson, Copyright (c) 2004 Intel Research Cambridge.
- */
-
-#include "xc_private.h"
-
-int xc_rrobin_global_set(int xc_handle, u64 slice)
-{
- dom0_op_t op;
- op.cmd = DOM0_SCHEDCTL;
- op.u.schedctl.sched_id = SCHED_RROBIN;
- op.u.schedctl.direction = SCHED_INFO_PUT;
-
- op.u.schedctl.u.rrobin.slice = slice;
- return do_dom0_op(xc_handle, &op);
-}
-
-
-int xc_rrobin_global_get(int xc_handle, u64 *slice)
-{
- dom0_op_t op;
- int ret;
-
- op.cmd = DOM0_SCHEDCTL;
- op.u.schedctl.sched_id = SCHED_RROBIN;
- op.u.schedctl.direction = SCHED_INFO_GET;
-
- ret = do_dom0_op(xc_handle, &op);
-
- *slice = op.u.schedctl.u.rrobin.slice;
-
- return ret;
-}
"cpu_khz", info.cpu_khz);
}
-static PyObject *pyxc_atropos_domain_set(PyObject *self,
- PyObject *args,
- PyObject *kwds)
-{
- XcObject *xc = (XcObject *)self;
- u32 domid;
- u64 period, slice, latency;
- int xtratime;
-
- static char *kwd_list[] = { "dom", "period", "slice", "latency",
- "xtratime", NULL };
-
- if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLi", kwd_list, &domid,
- &period, &slice, &latency, &xtratime) )
- return NULL;
-
- if ( xc_atropos_domain_set(xc->xc_handle, domid, period, slice,
- latency, xtratime) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
- Py_INCREF(zero);
- return zero;
-}
-
-static PyObject *pyxc_atropos_domain_get(PyObject *self,
- PyObject *args,
- PyObject *kwds)
-{
- XcObject *xc = (XcObject *)self;
- u32 domid;
- u64 period, slice, latency;
- int xtratime;
-
- static char *kwd_list[] = { "dom", NULL };
-
- if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
- return NULL;
-
- if ( xc_atropos_domain_get( xc->xc_handle, domid, &period,
- &slice, &latency, &xtratime ) )
- return PyErr_SetFromErrno(xc_error);
-
- return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
- "domain", domid,
- "period", period,
- "slice", slice,
- "latency", latency,
- "xtratime", xtratime);
-}
-
-
-static PyObject *pyxc_rrobin_global_set(PyObject *self,
- PyObject *args,
- PyObject *kwds)
-{
- XcObject *xc = (XcObject *)self;
- u64 slice;
-
- static char *kwd_list[] = { "slice", NULL };
-
- if( !PyArg_ParseTupleAndKeywords(args, kwds, "L", kwd_list, &slice) )
- return NULL;
-
- if ( xc_rrobin_global_set(xc->xc_handle, slice) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
- Py_INCREF(zero);
- return zero;
-}
-
static PyObject *pyxc_shadow_control(PyObject *self,
PyObject *args,
PyObject *kwds)
return zero;
}
-static PyObject *pyxc_rrobin_global_get(PyObject *self,
- PyObject *args,
- PyObject *kwds)
-{
- XcObject *xc = (XcObject *)self;
- u64 slice;
-
- if ( !PyArg_ParseTuple(args, "") )
- return NULL;
-
- if ( xc_rrobin_global_get(xc->xc_handle, &slice) != 0 )
- return PyErr_SetFromErrno(xc_error);
-
- return Py_BuildValue("{s:L}", "slice", slice);
-}
-
static PyObject *pyxc_domain_setmaxmem(PyObject *self,
PyObject *args,
PyObject *kwds)
" warpl [long]: Warp limit,\n"
},
- { "atropos_domain_set",
- (PyCFunction)pyxc_atropos_domain_set,
- METH_KEYWORDS, "\n"
- "Set the scheduling parameters for a domain when running with Atropos.\n"
- " dom [int]: domain to set\n"
- " period [long]: domain's scheduling period\n"
- " slice [long]: domain's slice per period\n"
- " latency [long]: wakeup latency hint\n"
- " xtratime [int]: boolean\n"
- "Returns: [int] 0 on success; -1 on error.\n" },
-
- { "atropos_domain_get",
- (PyCFunction)pyxc_atropos_domain_get,
- METH_KEYWORDS, "\n"
- "Get the current scheduling parameters for a domain when running with\n"
- "the Atropos scheduler."
- " dom [int]: domain to query\n"
- "Returns: [dict]\n"
- " domain [int]: domain ID\n"
- " period [long]: scheduler period\n"
- " slice [long]: CPU reservation per period\n"
- " latency [long]: unblocking latency hint\n"
- " xtratime [int] : 0 if not using slack time, nonzero otherwise\n" },
-
- { "rrobin_global_set",
- (PyCFunction)pyxc_rrobin_global_set,
- METH_KEYWORDS, "\n"
- "Set Round Robin scheduler slice.\n"
- " slice [long]: Round Robin scheduler slice\n"
- "Returns: [int] 0 on success, throws an exception on failure\n" },
-
- { "rrobin_global_get",
- (PyCFunction)pyxc_rrobin_global_get,
- METH_KEYWORDS, "\n"
- "Get Round Robin scheduler settings\n"
- "Returns [dict]:\n"
- " slice [long]: Scheduler time slice.\n" },
-
{ "evtchn_alloc_unbound",
(PyCFunction)pyxc_evtchn_alloc_unbound,
METH_VARARGS | METH_KEYWORDS, "\n"
def xend_node_log(self):
return self.xendGet(self.nodeurl('log'))
- def xend_node_cpu_rrobin_slice_set(self, slice):
- return self.xendPost(self.nodeurl(),
- {'op' : 'cpu_rrobin_slice_set',
- 'slice' : slice })
-
def xend_node_cpu_bvt_slice_set(self, ctx_allow):
return self.xendPost(self.nodeurl(),
{'op' : 'cpu_bvt_slice_set',
'warpl' : warpl,
'warpu' : warpu })
- def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_atropos_set',
- 'period' : period,
- 'slice' : slice,
- 'latency' : latency,
- 'xtratime': xtratime })
-
def xend_domain_maxmem_set(self, id, memory):
return self.xendPost(self.domainurl(id),
{ 'op' : 'maxmem_set',
except Exception, ex:
raise XendError(str(ex))
- def domain_cpu_atropos_set(self, id, period, slice, latency, xtratime):
- """Set Atropos scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup(id)
- try:
- return xc.atropos_domain_set(dominfo.dom, period, slice, latency, xtratime)
- except Exception, ex:
- raise XendError(str(ex))
-
- def domain_cpu_atropos_get(self, id):
- """Get Atropos scheduler parameters for a domain.
- """
- dominfo = self.domain_lookup(id)
- try:
- return xc.atropos_domain_get(dominfo.dom)
- except Exception, ex:
- raise XendError(str(ex))
-
def domain_device_create(self, id, devconfig):
"""Create a new device for a domain.
def cpu_bvt_slice_get(self):
return self.xc.bvtsched_global_get()
- def cpu_rrobin_slice_set(self, slice):
- return self.xc.rrobin_global_set(slice=slice)
-
- def cpu_rrobin_slice_get(self):
- return self.xc.rrobin_global_get()
-
def info(self):
return self.nodeinfo() + self.physinfo()
val = fn(req.args, {'dom': self.dom.id})
return val
- def op_cpu_atropos_set(self, op, req):
- fn = FormFn(self.xd.domain_cpu_atropos_set,
- [['dom', 'str'],
- ['period', 'int'],
- ['slice', 'int'],
- ['latency', 'int'],
- ['xtratime', 'int']])
- val = fn(req.args, {'dom': self.dom.id})
- return val
-
def op_maxmem_set(self, op, req):
fn = FormFn(self.xd.domain_maxmem_set,
[['dom', 'str'],
val = self.xn.reboot()
return val
- def op_cpu_rrobin_slice_set(self, op, req):
- fn = FormFn(self.xn.cpu_rrobin_slice_set,
- [['slice', 'int']])
- val = fn(req.args, {})
- return val
-
def op_cpu_bvt_slice_set(self, op, req):
fn = FormFn(self.xn.cpu_bvt_slice_set,
[['ctx_allow', 'int']])
val = fn(req.args, {'dom': self.dom.id})
return val
- def op_cpu_atropos_set(self, op, req):
- fn = FormFn(self.xd.domain_cpu_atropos_set,
- [['dom', 'str'],
- ['period', 'int'],
- ['slice', 'int'],
- ['latency', 'int'],
- ['xtratime', 'int']])
- val = fn(req.args, {'dom': self.dom.id})
- return val
-
def op_maxmem_set(self, op, req):
fn = FormFn(self.xd.domain_maxmem_set,
[['dom', 'str'],
xm.prog(ProgBvtslice)
-
-class ProgAtropos(Prog):
- group = 'scheduler'
- name= "atropos"
- info = """Set atropos parameters."""
-
- def help(self, args):
- print args[0], "DOM PERIOD SLICE LATENCY XTRATIME"
- print "\nSet atropos parameters."
-
- def main(self, args):
- if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
- dom = args[1]
- v = map(int, args[2:6])
- server.xend_domain_cpu_atropos_set(dom, *v)
-
-xm.prog(ProgAtropos)
-
-class ProgRrobin(Prog):
- group = 'scheduler'
- name = "rrobin"
- info = """Set round robin slice."""
-
- def help(self, args):
- print args[0], "SLICE"
- print "\nSet round robin scheduler slice."
-
- def main(self, args):
- if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
- rrslice = int(args[1])
- server.xend_node_rrobin_set(rrslice)
-
-xm.prog(ProgRrobin)
-
class ProgInfo(Prog):
group = 'host'
name = "info"
OBJS := $(subst trace.o,,$(OBJS))
endif
-OBJS := $(subst sched_atropos.o,,$(OBJS))
-OBJS := $(subst sched_rrobin.o,,$(OBJS))
-
default: common.o
common.o: $(OBJS)
$(LD) $(LDFLAGS) -r -o common.o $(OBJS)
arch_do_boot_vcpu(ed);
- sched_add_domain(ed);
-
if ( (rc = arch_set_info_guest(ed, c)) != 0 )
- {
- sched_rem_domain(ed);
goto out;
- }
+
+ sched_add_domain(ed);
/* domain_unpause_by_systemcontroller */
if ( test_and_clear_bit(EDF_CTRLPAUSE, &ed->ed_flags) )
+++ /dev/null
-/*
- * atropos.c
- * ---------
- *
- * Copyright (c) 1994 University of Cambridge Computer Laboratory.
- * This is part of Nemesis; consult your contract for terms and conditions.
- *
- * ID : $Id: atropos.c 1.1 Tue, 13 Apr 1999 13:30:49 +0100 dr10009 $
- *
- * This is the "atropos" CPU scheduler.
- */
-
-/* Ported to Xen's generic scheduler interface by Mark Williamson
- * these modifications are (C) 2004 Intel Research Cambridge
- */
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/lib.h>
-#include <xen/time.h>
-#include <xen/sched.h>
-#include <xen/sched-if.h>
-#include <public/sched_ctl.h>
-#include <xen/trace.h>
-
-#define ATROPOS_TASK_UNBLOCKED 16
-#define ATROPOS_TASK_WAIT 32
-#define ATROPOS_TASK_BLOCKED 48
-
-/* Atropos-specific per-domain data */
-struct at_dom_info
-{
- /* MAW Xen additions */
- struct domain *owner; /* the domain this data belongs to */
- struct list_head run_list; /* runqueue */
- struct list_head waitq; /* wait queue */
-
- /* (what remains of) the original fields */
-
- s_time_t deadline; /* Next deadline */
- s_time_t prevddln; /* Previous deadline */
-
- s_time_t remain; /* Time remaining this period */
- s_time_t period; /* Current period of time allocation */
- s_time_t nat_period; /* Natural period */
- s_time_t slice; /* Current length of allocation */
- s_time_t nat_slice; /* Natural length of allocation */
- s_time_t latency; /* Unblocking latency */
-
- int xtratime; /* Prepared to accept extra time? */
- int state; /* Keeps Atropos domain state */
-};
-
-/* Atropos-specific per-CPU data */
-struct at_cpu_info
-{
- struct list_head runq;
- struct list_head waitq;
-};
-
-
-#define DOM_INFO(_p) ((struct at_dom_info *)((_p)->sched_priv))
-#define CPU_INFO(_c) ((struct at_cpu_info *)((schedule_data[_c]).sched_priv))
-#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq)
-#define RUNQ(cpu) (&CPU_INFO(cpu)->runq)
-#define RUNLIST(_d) (&DOM_INFO(_d)->run_list)
-
-#define BESTEFFORT_QUANTUM MILLISECS(5)
-
-static void at_dump_cpu_state(int cpu);
-
-static inline void __add_to_runqueue_head(struct domain *d)
-{
- list_add(RUNLIST(d), RUNQ(d->processor));
-}
-
-static inline void __add_to_runqueue_tail(struct domain *d)
-{
- list_add_tail(RUNLIST(d), RUNQ(d->processor));
-}
-
-static inline void __del_from_runqueue(struct domain *d)
-{
- struct list_head *runlist = RUNLIST(d);
- list_del(runlist);
- runlist->next = NULL;
-}
-
-static inline int __task_on_runqueue(struct domain *d)
-{
- return (RUNLIST(d))->next != NULL;
-}
-
-
-/** calculate the length of a linked list */
-static int q_len(struct list_head *q)
-{
- int i = 0;
- struct at_dom_info *tmp;
- list_for_each_entry ( tmp, q, waitq )
- i++;
- return i;
-}
-
-
-/** waitq_el - get the domain that owns a wait queue list element */
-static inline struct domain *waitq_el(struct list_head *l)
-{
- struct at_dom_info *inf;
- inf = list_entry(l, struct at_dom_info, waitq);
- return inf->owner;
-}
-
-
-/*
- * requeue
- *
- * Places the specified domain on the appropriate queue.
- * The wait queue is ordered by the time at which the domain
- * will receive more CPU time. If a domain has no guaranteed time
- * left then the domain will be placed on the WAIT queue until
- * its next period.
- *
- * Note that domains can be on the wait queue with remain > 0
- * as a result of being blocked for a short time.
- * These are scheduled in preference to domains with remain < 0
- * in an attempt to improve interactive performance.
- */
-static void requeue(struct domain *sdom)
-{
- struct at_dom_info *i, *inf = DOM_INFO(sdom);
-
- if ( !domain_runnable(sdom) )
- return;
-
- if ( (inf->state == ATROPOS_TASK_WAIT) ||
- (inf->state == ATROPOS_TASK_UNBLOCKED) )
- {
- list_for_each_entry ( i, WAITQ(sdom->processor), waitq )
- {
- if ( i->deadline > inf->deadline )
- {
- __list_add(&inf->waitq, i->waitq.prev, &i->waitq);
- break;
- }
- }
-
- if ( &i->waitq == WAITQ(sdom->processor) )
- list_add_tail(&inf->waitq, WAITQ(sdom->processor));
- }
- else if ( domain_runnable(sdom) )
- {
- list_for_each_entry ( i, RUNQ(sdom->processor), run_list )
- {
- if ( (i->deadline > inf->deadline) || is_idle_task(i->owner) )
- {
- __list_add(&inf->run_list, i->run_list.prev, &i->run_list);
- break;
- }
- }
-
- if ( &i->waitq == RUNQ(sdom->processor) )
- list_add_tail(&inf->run_list, RUNQ(sdom->processor));
- }
- /* silently ignore tasks in other states like BLOCKED, DYING, STOPPED, etc
- * - they shouldn't be on any queue */
-}
-
-/** at_alloc_task - allocate private info for a task */
-static int at_alloc_task(struct domain *p)
-{
- ASSERT(p != NULL);
-
- p->sched_priv = xmalloc(struct at_dom_info);
- if ( p->sched_priv == NULL )
- return -1;
-
- return 0;
-}
-
-
-/* prepare a task to be added to scheduling */
-static void at_add_task(struct domain *p)
-{
- s_time_t now = NOW();
-
- ASSERT( p->sched_priv != NULL );
-
- DOM_INFO(p)->owner = p;
- p->lastschd = now;
-
- /* DOM 0's parameters must be set here for it to boot the system! */
- if(p->id == 0)
- {
- DOM_INFO(p)->remain = MILLISECS(15);
- DOM_INFO(p)->nat_period =
- DOM_INFO(p)->period = MILLISECS(20);
- DOM_INFO(p)->nat_slice =
- DOM_INFO(p)->slice = MILLISECS(15);
- DOM_INFO(p)->latency = MILLISECS(5);
- DOM_INFO(p)->xtratime = 1;
- DOM_INFO(p)->deadline = now;
- DOM_INFO(p)->prevddln = now;
- }
- else /* other domains run basically best effort unless otherwise set */
- {
- DOM_INFO(p)->remain = 0;
- DOM_INFO(p)->nat_period =
- DOM_INFO(p)->period = SECONDS(10);
- DOM_INFO(p)->nat_slice =
- DOM_INFO(p)->slice = MILLISECS(10);
- DOM_INFO(p)->latency = SECONDS(10);
- DOM_INFO(p)->xtratime = 1;
- DOM_INFO(p)->deadline = now;
-// DOM_INFO(p)->deadline = now + SECONDS(10);
- DOM_INFO(p)->prevddln = 0;
- }
-
- INIT_LIST_HEAD(&(DOM_INFO(p)->run_list));
- INIT_LIST_HEAD(&(DOM_INFO(p)->waitq));
-}
-
-/**
- * dequeue - remove a domain from any queues it is on.
- * @sdom: the task to remove
- */
-static void dequeue(struct domain *sdom)
-{
- struct at_dom_info *inf = DOM_INFO(sdom);
-
- ASSERT(sdom->id != IDLE_DOMAIN_ID);
-
- /* just delete it from all the queues! */
- list_del(&inf->waitq);
- INIT_LIST_HEAD(&inf->waitq);
-
-
- if(__task_on_runqueue(sdom))
- __del_from_runqueue(sdom);
-}
-
-
-/*
- * unblock
- *
- * This function deals with updating the sdom for a domain
- * which has just been unblocked.
- *
- * Xen's Atropos treats unblocking slightly differently to Nemesis:
- *
- * - "Short blocking" domains (i.e. that unblock before their deadline has
- * expired) are treated the same as in nemesis (put on the wait queue and
- * given preferential treatment in selecting domains for extra time).
- *
- * - "Long blocking" domains do not simply have their period truncated to their
- * unblocking latency as before but also have their slice recomputed to be the
- * same fraction of their new period. Each time the domain is scheduled, the
- * period and slice are doubled until they reach their original ("natural")
- * values, as set by the user (and stored in nat_period and nat_slice). The
- * idea is to give better response times to unblocking whilst preserving QoS
- * guarantees to other domains.
- */
-static void unblock(struct domain *sdom)
-{
- s_time_t time = NOW();
- struct at_dom_info *inf = DOM_INFO(sdom);
-
- dequeue(sdom);
-
- /* We distinguish two cases... short and long blocks */
- if ( inf->deadline < time )
- {
- /* Long blocking case */
-
- /* The sdom has passed its deadline since it was blocked.
- Give it its new deadline based on the latency value. */
- inf->prevddln = time;
-
- /* Scale the scheduling parameters as requested by the latency hint. */
- inf->deadline = time + inf->latency;
- inf->slice = inf->nat_slice / ( inf->nat_period / inf->latency );
- inf->period = inf->latency;
- inf->remain = inf->slice;
- }
- else
- {
- /* Short blocking case */
-
- /* We leave REMAIN intact, but put this domain on the WAIT
- queue marked as recently unblocked. It will be given
- priority over other domains on the wait queue until while
- REMAIN>0 in a generous attempt to help it make up for its
- own foolishness. */
- if(inf->remain > 0)
- inf->state = ATROPOS_TASK_UNBLOCKED;
- else
- inf->state = ATROPOS_TASK_WAIT;
- }
-
- requeue(sdom);
-}
-
-
-static int at_init_idle_task(struct domain *p)
-{
- if(at_alloc_task(p) < 0) return -1;
-
- at_add_task(p);
-
- dequeue(p);
- requeue(p);
-
- return 0;
-}
-
-
-static void block(struct domain* sdom)
-{
- DOM_INFO(sdom)->state = ATROPOS_TASK_BLOCKED;
- dequeue(sdom);
- requeue(sdom);
-}
-
-
-/**
- * ATROPOS - main scheduler function
- */
-struct task_slice ksched_scheduler(s_time_t time)
-{
- struct domain *cur_sdom = current; /* Current sdom */
- s_time_t newtime;
- s_time_t ranfor; /* How long the domain ran */
- struct domain *sdom; /* tmp. scheduling domain */
- int cpu = cur_sdom->processor; /* current CPU */
- struct at_dom_info *cur_info;
- static unsigned long waitq_rrobin = 0;
- int i;
- struct task_slice ret;
-
-
- cur_info = DOM_INFO(cur_sdom);
-
- ASSERT( cur_sdom != NULL);
-
- /* If we were spinning in the idle loop, there is no current
- * domain to deschedule. */
- if (is_idle_task(cur_sdom))
- goto deschedule_done;
-
- /*****************************
- *
- * Deschedule the current scheduling domain
- *
- ****************************/
-
- /* Record the time the domain was preempted and for how long it
- ran. Work out if the domain is going to be blocked to save
- some pointless queue shuffling */
- cur_sdom->lastdeschd = time;
-
- ranfor = (time - cur_sdom->lastschd);
-
- dequeue(cur_sdom);
-
- if ( domain_runnable(cur_sdom) ||
- (cur_info->state == ATROPOS_TASK_UNBLOCKED) )
- {
-
- /* In this block, we are doing accounting for an sdom which has
- been running in contracted time. Note that this could now happen
- even if the domain is on the wait queue (i.e. if it blocked) */
-
- /* Deduct guaranteed time from the domain */
- cur_info->remain -= ranfor;
-
- /* If guaranteed time has run out... */
- if ( cur_info->remain <= 0 )
- {
- /* Move domain to correct position in WAIT queue */
- /* XXX sdom_unblocked doesn't need this since it is
- already in the correct place. */
- cur_info->state = ATROPOS_TASK_WAIT;
- }
- }
-
- requeue(cur_sdom);
-
- deschedule_done:
- /*****************************
- *
- * We have now successfully descheduled the current sdom.
- * The next task is the allocate CPU time to any sdom it is due to.
- *
- ****************************/
- cur_sdom = NULL;
-
- /*****************************
- *
- * Allocate CPU time to any waiting domains who have passed their
- * period deadline. If necessary, move them to run queue.
- *
- ****************************/
-
- while(!list_empty(WAITQ(cpu)) &&
- DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time )
- {
-
- struct at_dom_info *inf = DOM_INFO(sdom);
- dequeue(sdom);
-
- if ( inf->period != inf->nat_period )
- {
- /* This domain has had its parameters adjusted as a result of
- * unblocking and they need to be adjusted before requeuing it */
- inf->slice *= 2;
- inf->period *= 2;
-
- if ( inf->period > inf->nat_period )
- {
- inf->period = inf->nat_period;
- inf->slice = inf->nat_slice;
- }
- }
-
- /* Domain begins a new period and receives a slice of CPU
- * If this domain has been blocking then throw away the
- * rest of it's remain - it can't be trusted */
- if (inf->remain > 0)
- inf->remain = inf->slice;
- else
- inf->remain += inf->slice;
-
- inf->prevddln = inf->deadline;
- inf->deadline += inf->period;
-
- if ( inf->remain <= 0 )
- inf->state = ATROPOS_TASK_WAIT;
-
- /* Place on the appropriate queue */
- requeue(sdom);
- }
-
- /*****************************
- *
- * Next we need to pick an sdom to run.
- * If anything is actually 'runnable', we run that.
- * If nothing is, we pick a waiting sdom to run optimistically.
- * If there aren't even any of those, we have to spin waiting for an
- * event or a suitable time condition to happen.
- *
- ****************************/
-
- /* we guarantee there's always something on the runqueue */
- cur_info = list_entry(RUNQ(cpu)->next,
- struct at_dom_info, run_list);
-
- cur_sdom = cur_info->owner;
- newtime = time + cur_info->remain;
-
- /* MAW - the idle domain is always on the run queue. We run from the
- * runqueue if it's NOT the idle domain or if there's nothing on the wait
- * queue */
- if (cur_sdom->id == IDLE_DOMAIN_ID && !list_empty(WAITQ(cpu)))
- {
- struct at_dom_info *inf;
-
- /* Try running a domain on the WAIT queue - this part of the
- scheduler isn't particularly efficient but then again, we
- don't have any guaranteed domains to worry about. */
-
- /* See if there are any unblocked domains on the WAIT
- queue who we can give preferential treatment to. */
-
- list_for_each_entry ( inf, WAITQ(cpu), waitq )
- {
- sdom = inf->owner;
-
- if (inf->state == ATROPOS_TASK_UNBLOCKED)
- {
- cur_sdom = sdom;
- cur_info = inf;
- newtime = time + inf->remain;
- goto found;
- }
- }
-
- /* init values needed to approximate round-robin for slack time */
- i = 0;
- if ( waitq_rrobin >= q_len(WAITQ(cpu)))
- waitq_rrobin = 0;
-
-
- /* Last chance: pick a domain on the wait queue with the XTRA
- flag set. The NEXT_OPTM field is used to cheaply achieve
- an approximation of round-robin order */
- list_for_each_entry ( inf, WAITQ(cpu), waitq )
- {
- sdom = inf->owner;
-
- if (inf->xtratime && i >= waitq_rrobin)
- {
- cur_sdom = sdom;
- cur_info = inf;
- newtime = time + BESTEFFORT_QUANTUM;
- waitq_rrobin = i + 1; /* set this value ready for next */
- goto found;
- }
-
- i++;
- }
- }
-
- found:
- /**********************
- *
- * We now have to work out the time when we next need to
- * make a scheduling decision. We set the alarm timer
- * to cause an interrupt at that time.
- *
- **********************/
-
-#define MIN(x,y) ( ( x < y ) ? x : y )
-#define MAX(x,y) ( ( x > y ) ? x : y )
-
- /* If we might be able to run a waiting domain before this one has */
- /* exhausted its time, cut short the time allocation */
- if (!list_empty(WAITQ(cpu)))
- {
- newtime = MIN(newtime,
- DOM_INFO(waitq_el(WAITQ(cpu)->next))->deadline);
- }
-
- /* don't allow pointlessly small time slices */
- newtime = MAX(newtime, time + BESTEFFORT_QUANTUM);
-
- ret.task = cur_sdom;
- ret.time = newtime - time;
-
- TRACE_1D(0, cur_sdom->id);
-
- return ret;
-}
-
-
-/* set up some private data structures */
-static int at_init_scheduler()
-{
- int i;
-
- for ( i = 0; i < NR_CPUS; i++ )
- {
- schedule_data[i].sched_priv = xmalloc(sizeof(struct at_cpu_info));
- if ( schedule_data[i].sched_priv == NULL )
- return -1;
- INIT_LIST_HEAD(WAITQ(i));
- INIT_LIST_HEAD(RUNQ(i));
- }
-
- return 0;
-}
-
-
-/* print relevant per-domain info for a run queue dump */
-static void at_dump_runq_el(struct domain *p)
-{
- printk("lastschd = %llu, xtratime = %d ",
- p->lastschd, DOM_INFO(p)->xtratime);
-}
-
-
-/* dump relevant per-cpu state for a run queue dump */
-static void at_dump_cpu_state(int cpu)
-{
- struct list_head *queue;
- int loop = 0;
- struct at_dom_info *d_inf;
- struct domain *d;
-
- queue = RUNQ(cpu);
- printk("\nRUNQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
- (unsigned long) queue->next, (unsigned long) queue->prev);
-
- list_for_each_entry ( d_inf, queue, run_list )
- {
- d = d_inf->owner;
- printk("%3d: %d has=%c ", loop++, d->id,
- test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
- at_dump_runq_el(d);
- printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
- printk(" l: %lx n: %lx p: %lx\n",
- (unsigned long)&d_inf->run_list,
- (unsigned long)d_inf->run_list.next,
- (unsigned long)d_inf->run_list.prev);
- }
-
-
- queue = WAITQ(cpu);
- printk("\nWAITQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
- (unsigned long) queue->next, (unsigned long) queue->prev);
-
- list_for_each_entry ( d_inf, queue, waitq )
- {
- d = d_inf->owner;
- printk("%3d: %d has=%c ", loop++, d->id,
- test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
- at_dump_runq_el(d);
- printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
- printk(" l: %lx n: %lx p: %lx\n",
- (unsigned long)&d_inf->waitq,
- (unsigned long)d_inf->waitq.next,
- (unsigned long)d_inf->waitq.prev);
- }
-
-}
-
-/* set or fetch domain scheduling parameters */
-static int at_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
-{
- if ( cmd->direction == SCHED_INFO_PUT )
- {
- /* sanity checking! */
- if( cmd->u.atropos.latency > cmd->u.atropos.nat_period
- || cmd->u.atropos.latency == 0
- || cmd->u.atropos.nat_slice > cmd->u.atropos.nat_period )
- return -EINVAL;
-
- DOM_INFO(p)->nat_period = cmd->u.atropos.nat_period;
- DOM_INFO(p)->nat_slice = cmd->u.atropos.nat_slice;
- DOM_INFO(p)->latency = cmd->u.atropos.latency;
- DOM_INFO(p)->xtratime = !!cmd->u.atropos.xtratime;
- }
- else if ( cmd->direction == SCHED_INFO_GET )
- {
- cmd->u.atropos.nat_period = DOM_INFO(p)->nat_period;
- cmd->u.atropos.nat_slice = DOM_INFO(p)->nat_slice;
- cmd->u.atropos.latency = DOM_INFO(p)->latency;
- cmd->u.atropos.xtratime = DOM_INFO(p)->xtratime;
- }
-
- return 0;
-}
-
-/* free memory associated with a task */
-static void at_free_task(struct domain *p)
-{
- xfree( DOM_INFO(p) );
-}
-
-
-/* print decoded domain private state value (if known) */
-static int at_prn_state(int state)
-{
- int ret = 0;
-
- switch(state)
- {
- case ATROPOS_TASK_UNBLOCKED:
- printk("Unblocked");
- break;
- case ATROPOS_TASK_WAIT:
- printk("Wait");
- break;
- default:
- ret = -1;
- }
-
- return ret;
-}
-
-struct scheduler sched_atropos_def = {
- .name = "Atropos Soft Real Time Scheduler",
- .opt_name = "atropos",
- .sched_id = SCHED_ATROPOS,
- .init_scheduler = at_init_scheduler,
- .init_idle_task = at_init_idle_task,
- .alloc_task = at_alloc_task,
- .add_task = at_add_task,
- .free_task = at_free_task,
- .wake = unblock,
- .sleep = block,
- .do_schedule = ksched_scheduler,
- .adjdom = at_adjdom,
- .dump_cpu_state = at_dump_cpu_state,
- .prn_state = at_prn_state,
-};
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
+++ /dev/null
-/****************************************************************************
- * Round Robin Scheduler for Xen
- *
- * by Mark Williamson (C) 2004 Intel Research Cambridge
- */
-
-#include <xen/sched.h>
-#include <xen/sched-if.h>
-#include <public/sched_ctl.h>
-#include <xen/ac_timer.h>
-#include <xen/softirq.h>
-#include <xen/time.h>
-#include <xen/slab.h>
-
-#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */
-
-static s_time_t rr_slice = MILLISECS(10);
-
-/* Only runqueue pointers and domain pointer*/
-struct rrobin_dom_info
-{
- struct list_head run_list;
- struct domain *domain;
-};
-
-#define RR_INFO(d) ((struct rrobin_dom_info *)d->sched_priv)
-#define RUNLIST(d) ((struct list_head *)&(RR_INFO(d)->run_list))
-#define RUNQUEUE(cpu) RUNLIST(schedule_data[cpu].idle)
-
-static inline void __add_to_runqueue_head(struct domain *d)
-{
- list_add(RUNLIST(d), RUNQUEUE(d->processor));
-}
-
-static inline void __add_to_runqueue_tail(struct domain *d)
-{
- list_add_tail(RUNLIST(d), RUNQUEUE(d->processor));
-}
-
-static inline void __del_from_runqueue(struct domain *d)
-{
- struct list_head *runlist = RUNLIST(d);
- list_del(runlist);
- runlist->next = NULL;
-}
-
-static inline int __task_on_runqueue(struct domain *d)
-{
- return (RUNLIST(d))->next != NULL;
-}
-
-/* Initialises the runqueues and creates the domain info cache */
-static int rr_init_scheduler()
-{
- int i;
-
- for ( i = 0; i < NR_CPUS; i++ )
- INIT_LIST_HEAD(RUNQUEUE(i));
-
- return 0;
-}
-/* Allocates memory for per domain private scheduling data*/
-static int rr_alloc_task(struct domain *d)
-{
- if ( (d->sched_priv = new(struct rrobin_dom_info) == NULL )
- return -1;
- memset(d->sched_priv, 0, sizeof(struct rrobin_dom_info));
- return 0;
-}
-
-/* Setup the rr_dom_info */
-static void rr_add_task(struct domain *d)
-{
- struct rrobin_dom_info *inf;
- RR_INFO(d)->domain = d;
- inf = RR_INFO(d);
-}
-
-/* Frees memory used by domain info */
-static void rr_free_task(struct domain *d)
-{
- ASSERT(d->sched_priv != NULL);
- xfree(d->sched_priv);
-}
-
-/* Initialises idle task */
-static int rr_init_idle_task(struct domain *d)
-{
- if ( rr_alloc_task(d) < 0 )
- return -1;
-
- rr_add_task(d);
-
- set_bit(DF_RUNNING, &d->flags);
- if ( !__task_on_runqueue(d) )
- __add_to_runqueue_head(d);
-
- return 0;
-}
-
-/* Main scheduling function */
-static struct task_slice rr_do_schedule(s_time_t now)
-{
- struct domain *prev = current;
- int cpu = current->processor;
- struct task_slice ret;
-
- if ( !is_idle_task(prev) )
- {
- __del_from_runqueue(prev);
-
- if ( domain_runnable(prev) )
- __add_to_runqueue_tail(prev);
- }
-
- ret.task = list_entry(RUNQUEUE(cpu)->next,
- struct rrobin_dom_info,
- run_list)->domain;
- ret.time = rr_slice;
- return ret;
-}
-
-/* Set/retrive control parameter(s) */
-static int rr_ctl(struct sched_ctl_cmd *cmd)
-{
- if ( cmd->direction == SCHED_INFO_PUT )
- {
- rr_slice = cmd->u.rrobin.slice;
- }
- else /* cmd->direction == SCHED_INFO_GET */
- {
- cmd->u.rrobin.slice = rr_slice;
- }
-
- return 0;
-}
-
-static void rr_dump_settings()
-{
- printk("rr_slice = %llu ", rr_slice);
-}
-
-static void rr_sleep(struct domain *d)
-{
- if ( test_bit(DF_RUNNING, &d->flags) )
- cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ);
- else if ( __task_on_runqueue(d) )
- __del_from_runqueue(d);
-}
-
-void rr_wake(struct domain *d)
-{
- struct domain *curr;
- s_time_t now;
- int cpu = d->processor;
-
- if ( unlikely(__task_on_runqueue(d)) )
- return;
-
- __add_to_runqueue_head(d);
-
- now = NOW();
-
- curr = schedule_data[cpu].curr;
- if ( is_idle_task(curr) )
- cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
-}
-
-
-static void rr_dump_domain(struct domain *d)
-{
- printk("%u has=%c ", d->id,
- test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
- printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
-}
-
-static void rr_dump_cpu_state(int i)
-{
- struct list_head *queue;
- int loop = 0;
- struct rrobin_dom_info *d_inf;
-
- queue = RUNQUEUE(i);
- printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
- (unsigned long) queue->next, (unsigned long) queue->prev);
-
- printk("%3d: ",loop++);
- d_inf = list_entry(queue, struct rrobin_dom_info, run_list);
- rr_dump_domain(d_inf->domain);
-
- list_for_each_entry ( d_inf, queue, run_list )
- {
- printk("%3d: ",loop++);
- rr_dump_domain(d_inf->domain);
- }
-}
-
-
-struct scheduler sched_rrobin_def = {
- .name = "Round-Robin Scheduler",
- .opt_name = "rrobin",
- .sched_id = SCHED_RROBIN,
-
- .init_idle_task = rr_init_idle_task,
- .alloc_task = rr_alloc_task,
- .add_task = rr_add_task,
- .free_task = rr_free_task,
- .init_scheduler = rr_init_scheduler,
- .do_schedule = rr_do_schedule,
- .control = rr_ctl,
- .dump_settings = rr_dump_settings,
- .dump_cpu_state = rr_dump_cpu_state,
- .sleep = rr_sleep,
- .wake = rr_wake,
-};
-
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
/* Block the currently-executing domain until a pertinent event occurs. */
long do_block(void)
{
- ASSERT(current->domain->id != IDLE_DOMAIN_ID);
- current->vcpu_info->evtchn_upcall_mask = 0;
- set_bit(EDF_BLOCKED, ¤t->ed_flags);
- TRACE_2D(TRC_SCHED_BLOCK, current->domain->id, current);
- __enter_scheduler();
+ struct exec_domain *ed = current;
+
+ TRACE_2D(TRC_SCHED_BLOCK, ed->domain->id, ed);
+
+ ed->vcpu_info->evtchn_upcall_mask = 0;
+ set_bit(EDF_BLOCKED, &ed->ed_flags);
+
+ /* Check for events /after/ blocking: avoids wakeup waiting race. */
+ if ( event_pending(ed) )
+ clear_bit(EDF_BLOCKED, &ed->ed_flags);
+ else
+ __enter_scheduler();
+
return 0;
}
ASSERT(!in_irq());
- if ( test_bit(EDF_BLOCKED, &prev->ed_flags) )
- {
- /* This check is needed to avoid a race condition. */
- if ( event_pending(prev) )
- clear_bit(EDF_BLOCKED, &prev->ed_flags);
- else
- SCHED_OP(do_block, prev);
- }
-
prev->cpu_time += now - prev->lastschd;
/* get policy-specific decision on scheduling... */
* This makes sure that old versions of dom0 tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
-#define DOM0_INTERFACE_VERSION 0xAAAA1003
+#define DOM0_INTERFACE_VERSION 0xAAAA1004
/************************************************************************/
-/**
+/******************************************************************************
* Generic scheduler control interface.
*
* Mark Williamson, (C) 2004 Intel Research Cambridge
#ifndef __XEN_PUBLIC_SCHED_CTL_H__
#define __XEN_PUBLIC_SCHED_CTL_H__
-/* Scheduler types */
+/* Scheduler types. */
#define SCHED_BVT 0
-#define SCHED_ATROPOS 2
-#define SCHED_RROBIN 3
-/* these describe the intended direction used for a scheduler control or domain
- * command */
+/* Set or get info? */
#define SCHED_INFO_PUT 0
#define SCHED_INFO_GET 1
*/
struct sched_ctl_cmd
{
- u32 sched_id; /* 0 */
- u32 direction; /* 4 */
- union { /* 8 */
- struct bvt_ctl
- {
- /* IN variables. */
- u32 ctx_allow; /* 8: context switch allowance */
- } PACKED bvt;
-
- struct rrobin_ctl
- {
- /* IN variables */
- u64 slice; /* 8: round robin time slice */
- } PACKED rrobin;
- } PACKED u;
-} PACKED; /* 16 bytes */
+ u32 sched_id;
+ u32 direction;
+ union {
+ struct bvt_ctl {
+ u32 ctx_allow;
+ } bvt;
+ } u;
+};
struct sched_adjdom_cmd
{
- u32 sched_id; /* 0 */
- u32 direction; /* 4 */
- domid_t domain; /* 8 */
- u16 __pad0;
- u32 __pad1;
- union { /* 16 */
- struct bvt_adjdom
- {
- u32 mcu_adv; /* 16: mcu advance: inverse of weight */
- u32 warpback; /* 20: warp? */
- s32 warpvalue; /* 24: warp value */
- long long warpl; /* 32: warp limit */
- long long warpu; /* 40: unwarp time requirement */
- } PACKED bvt;
-
- struct atropos_adjdom
- {
- u64 nat_period; /* 16 */
- u64 nat_slice; /* 24 */
- u64 latency; /* 32 */
- u32 xtratime; /* 36 */
- } PACKED atropos;
- } PACKED u;
-} PACKED; /* 40 bytes */
+ u32 sched_id;
+ u32 direction;
+ domid_t domain;
+ union {
+ struct bvt_adjdom {
+ u32 mcu_adv; /* mcu advance: inverse of weight */
+ u32 warpback; /* warp? */
+ s32 warpvalue; /* warp value */
+ long long warpl; /* warp limit */
+ long long warpu; /* unwarp time requirement */
+ } bvt;
+ } u;
+};
#endif /* __XEN_PUBLIC_SCHED_CTL_H__ */
char *opt_name; /* option name for this scheduler */
unsigned int sched_id; /* ID for this scheduler */
- int (*init_scheduler) ();
+ int (*init_scheduler) (void);
int (*init_idle_task) (struct exec_domain *);
int (*alloc_task) (struct exec_domain *);
void (*add_task) (struct exec_domain *);
void (*rem_task) (struct exec_domain *);
void (*sleep) (struct exec_domain *);
void (*wake) (struct exec_domain *);
- void (*do_block) (struct exec_domain *);
struct task_slice (*do_schedule) (s_time_t);
int (*control) (struct sched_ctl_cmd *);
int (*adjdom) (struct domain *,
struct sched_adjdom_cmd *);
void (*dump_settings) (void);
void (*dump_cpu_state) (int);
- int (*prn_state) (int);
};
extern struct schedule_data schedule_data[];